//=============================================================================
//
//		Copyright (C) 1995,1996 by Paul S. McCarthy and Eric Sunshine.
//				Written by Paul S. McCarthy and Eric Sunshine.
//							All Rights Reserved.
//
//		This notice may not be removed from this source code.
//
//		This object is included in the MiscKit by permission from the authors
//		and its use is governed by the MiscKit license, found in the file
//		"License.rtf" in the MiscKit distribution.	Please refer to that file
//		for a list of all applicable permissions and restrictions.
//
//=============================================================================
//-----------------------------------------------------------------------------
// NameCache.m
//
//		Data structure and routines for caching user names and group names.
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// $Id$
// $Log$
//-----------------------------------------------------------------------------

#import "NameCache.h"
#import <grp.h>
#import <pwd.h>

static NXZone* theZone = 0;


//-----------------------------------------------------------------------------
// store_string
//-----------------------------------------------------------------------------
static char const* store_string( char const* s )
	{
	char* t = 0;
	if (s != 0)
		t = NXCopyStringBufferFromZone( s, theZone );
	return t;
	}


//-----------------------------------------------------------------------------
// str_int
//-----------------------------------------------------------------------------
static char const* str_int( int x )
	{
	static char buff[ 32 ];
	sprintf( buff, "%d", x );
	return buff;
	}



//=============================================================================
// NAME CACHE
//=============================================================================
@implementation NameCache
//-----------------------------------------------------------------------------
// + initialize
//-----------------------------------------------------------------------------
+ initialize
	{
	if (theZone == 0)
		{
		theZone = NXCreateZone( vm_page_size, vm_page_size, NO );
		}
	return self;
	}


//-----------------------------------------------------------------------------
// - init
//-----------------------------------------------------------------------------
- init
	{
	[super init];
	table = [[HashTable alloc] initKeyDesc:"i" valueDesc:"*"];
	return self;
	}


//-----------------------------------------------------------------------------
// - resolve:
//-----------------------------------------------------------------------------
- (char const*) resolve:(int)x
	{
	[self subclassResponsibility:_cmd];
	return 0;
	}


//-----------------------------------------------------------------------------
// - store:
//-----------------------------------------------------------------------------
- (char const*) store:(int)ident
	{
	char const* name = store_string( [self resolve:ident] );
	[table insertKey:(void const*)ident value:(void*)name];
	return name;
	}


//-----------------------------------------------------------------------------
// - lookup:
//-----------------------------------------------------------------------------
- (char const*) lookup:(int)ident
	{
	char const* name = 0;
	if ([table isKey:(void const*)ident])
		name = [table valueForKey:(void const*)ident];
	else
		name = [self store:ident];
	return name;
	}

@end


//=============================================================================
// OWNER CACHE
//=============================================================================
@implementation OwnerCache
//-----------------------------------------------------------------------------
// - resolve:
//-----------------------------------------------------------------------------
- (char const*) resolve:(int)uid
	{
	char const* s = 0;
	struct passwd const* const pw = getpwuid( uid );
	if (pw != 0)
		s = pw->pw_name;
	else
		s = str_int( uid );
	return s;
	}


//-----------------------------------------------------------------------------
// + commonInstance
//-----------------------------------------------------------------------------
+ commonInstance
	{
	static id obj = 0;
	if (obj == 0)
		obj = [[self allocFromZone:theZone] init];
	return obj;
	}
@end


//=============================================================================
// GROUP CACHE
//=============================================================================
@implementation GroupCache
//-----------------------------------------------------------------------------
// - resolve:
//-----------------------------------------------------------------------------
- (char const*) resolve:(int)gid
	{
	char const* s = 0;
	struct group const* const gr = getgrgid( gid );
	if (gr != 0)
		s = gr->gr_name;
	else
		s = str_int( gid );
	return s;
	}


//-----------------------------------------------------------------------------
// + commonInstance
//-----------------------------------------------------------------------------
+ commonInstance
	{
	static id obj = 0;
	if (obj == 0)
		obj = [[self allocFromZone:theZone] init];
	return obj;
	}
@end
